package com.zhan.webflux.controller;

import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import io.netty.util.internal.ThreadLocalRandom;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/*
 *@Description<p></p>
 *@Author gz
 *@CreateTime 2025/7/22 10:06
 *@CopyRight @2021-2025 卓望信息技术（北京）公司
 */
@RestController
public class SSEController {


    @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> getSSE() {
        return Flux.range(1, 10)
                .map(integer -> {
                    return ServerSentEvent.builder("haha-" + integer)
                            .comment("备注" + integer)
                            .data("haha-" + integer)
                            .id("id-" + integer)
                            .build();
                })
                .delayElements(Duration.ofMillis(500));

    }

    /**
     * 每秒推送一次当前服务器时间
     * 浏览器访问: http://localhost:8080/sse/time
     */
    @GetMapping(value = "/sse/time", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamTime() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return Flux.interval(Duration.ofSeconds(1))
                .map(seq -> ServerSentEvent.<String>builder()
                        .id(String.valueOf(seq))
                        .event("time")
                        .data("Server time: " + LocalTime.now())
                        .build());
    }

    // 股票行情：随机价格
    @GetMapping(value = "/sse/stocks/{code}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<StockPrice>> stocks(@PathVariable String code) {
        return Flux.interval(Duration.ofMillis(500))
                .map(i -> new StockPrice(code, ThreadLocalRandom.current().nextDouble(100, 110)))
                .map(sp -> ServerSentEvent.<StockPrice>builder()
                        .event("price")
                        .data(sp)
                        .build());
    }

    record StockPrice(String code, double price) {
    }
}
